/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "数学.h"

#include <矩阵.h>

#include <thread>
#include <omp.h>

using namespace std;


void f_线程_计算顶点集最大包围(vec3* v, uint32 num, vec3* 结果) {
	for (uint32 i = 0; i < num; ++i) {
		*(结果) = vec_Max(*(结果), v[i]);
	}
}

void f_线程_计算顶点集最小包围(vec3* v, uint32 num, vec3* 结果) {
	for (uint32 i = 0; i < num; ++i) {
		*(结果) = vec_Min(*(结果), v[i]);
	}
}


mat3X3 f_get坐标集包围盒(vec3* v, uint32 num) {
	mat3X3 box = { {100000000.0, 100000000.0, 100000000.0},   {-100000000.0, -100000000.0, -100000000.0},   {0.0, 0.0, 0.0} };

	thread t[2];
	t[0] = thread(f_线程_计算顶点集最小包围, v, num, &box.row0);
	t[1] = thread(f_线程_计算顶点集最大包围, v, num, &box.row1);
	
	t[0].join();
	t[1].join();

	box.row2 = vec_sub(box.row1, box.row0);

	return box;
}

float32 f_get坐标集包围球(vec3* v, uint32 num) {

	return float32();
}






S_Sphere f_graph_取三角形球形包围(vec3* 三角形) {
	S_Sphere s;
	s.pos = { (三角形[0].x + 三角形[1].x + 三角形[2].x) / 3.0f,
				(三角形[0].y + 三角形[1].y + 三角形[2].y) / 3.0f,
				(三角形[0].z + 三角形[1].z + 三角形[2].z) / 3.0f
	};

	s.radius = vec_len(s.pos - 三角形[0]);
	s.radius = DEF_Max(s.radius, vec_len(s.pos - 三角形[1]));
	s.radius = DEF_Max(s.radius, vec_len(s.pos - 三角形[2]));

	return s;
}


#include <random>

void f_随机向量(std::vector<S_Sphere>& vec, uint64 num, const S_Sphere& 最小, const S_Sphere& 最大, int32 种子) {
	std::default_random_engine e(种子);
	std::uniform_real_distribution<float32> dis_x(DEF_Min(最小.pos.x, 最大.pos.x), DEF_Max(最小.pos.x, 最大.pos.x));
	std::uniform_real_distribution<float32> dis_y(DEF_Min(最小.pos.y, 最大.pos.y), DEF_Max(最小.pos.y, 最大.pos.y));
	std::uniform_real_distribution<float32> dis_z(DEF_Min(最小.pos.z, 最大.pos.z), DEF_Max(最小.pos.z, 最大.pos.z));
	std::uniform_real_distribution<float32> dis(DEF_Min(最小.radius, 最大.radius), DEF_Max(最小.radius, 最大.radius));

	vec.resize(num);
	auto* v = vec.data();

	if (num > 3000) {
#pragma omp parallel for
		for (int64 i = 0; i < num; ++i) {
			v[i].pos = vec3{ dis_x(e), dis_y(e), dis_z(e) };
			v[i].radius = dis(e);
		}

		return;
	}

	for (int64 i = 0; i < num; ++i) {
		v[i].pos = vec3{ dis_x(e), dis_y(e), dis_z(e) };
		v[i].radius = dis(e);
	}
}

int32 f_meth_刻度缩放(float32& 跨度, float32 scale, int32 细分, int32 进制) {
	跨度 *= scale;

	float32 刻度数值跨度 = 1 / scale;
	int32 缩放比 = max(刻度数值跨度, 1);
	缩放比 = pow(进制, int32(log2(缩放比)));

	float32 跨度1 = 跨度 * 缩放比;


	int32 remainder = 缩放比 <= 1 ? 1 : 缩放比*细分;
	if (scale > 1) {
		缩放比 = pow(2, int32(log2(scale)));
		remainder = max(5 / 缩放比, 1);
		if(缩放比 == 1) {
			跨度1 = 跨度;
		}
		else if(缩放比 == 2) {
			跨度1 = 跨度 * 2 / 细分;
		}
		else {
			跨度1 = 跨度 * 2 / 10;
		}
	}
	else {
		remainder = 缩放比*5;
	}

	跨度 = 跨度1;
    return remainder;
}


